// vue自定义指令限制输入框
export const regexObj = {
    // VIN
    vin:/[^\w]/g,
    // 只允许单纯数字输入
    number:/\D/g,
    // 禁止中文输入
    noChinese:/[\u4e00-\u9fa5]/g,
    // 电话号码
    phone:/[a-zA-Z\u4e00-\u9fa5]/,
    // 身份证号码
    idCard:/[^A-Za-z[0-9]/g,
    // 姓名
    insuranceUserName:/[^\u4e00-\u9fa5a-zA-Z0-9;；()（）]/g,
    // 金额
    amount:'amountFn'
}

class InputValidator {
    constructor(el, binding, vnode) {
        // input实例
        this.inputDom = el.querySelector('input') || el
        // 绑定的dom实例
        this.el = el
        // 限制输入长度
        this.maxLength = this.inputDom.getAttribute('maxlength') || 500
        // 最大值限制
        this.max =  this.inputDom.getAttribute('max') || '999999999.99'
        // 当前绑定的类型 Array
        this.binding = Object.keys(binding.modifiers)
        // 当前绑定dom的vnode
        this.vnode = vnode
    }
    // 正则表达式限制输入
    regexFn = (e,regex) => {
        if(isInvalid(e)) return null
        e = numberToString(e)
        return e.replace(regex,'')
    }
    // v-input-valid.amount 金额输入（默认保留两位小数）
    amountFn = () => {
        this.maxLength = 12
        this.vnode.componentInstance.$watch('value',(newValue,oldValue)=>{
            if(isInvalid(newValue)) return
            newValue = numberToString(newValue).replace(/[^0-9.]/g,'')
            const flag = newValue.split('.').length>2 || newValue.split('.')[1]?.length>2
            if(flag){
                this.update(oldValue)
            }else{
                if(newValue[0]==='.') newValue = '0'+newValue
                this.update(newValue)
            }
        })
        this.inputDom.addEventListener('blur',(e)=>{
            let num = +e.target.value
            if(isInvalid(num)) return this.update('')
            if(num > this.max) return this.update(this.max)
            this.update(num.toLocaleString('zh', {
                minimumFractionDigits: 2,
                useGrouping: false
            }))
        })
    }
    // 回填更新数据数据
    update = (newValue) => {
        this.vnode.data.model.callback(newValue.slice(0,this.maxLength))
    }
}
// 自定义指令
const input_valid = {
    bind(el, binding, vnode) {
        const inputValid = new InputValidator(el, binding, vnode)
        // 绑定类型
        const type = inputValid.binding[0]
        // 绑定方法/正则
        const valid = regexObj[type]
        switch (typeof regexObj[type]) {
            // 当前需要添加单纯正则限制输入
            case 'object':
                vnode.componentInstance.$watch('value',(newValue,oldValue) => {
                    if(isInvalid(newValue)||(newValue == oldValue)) return
                    inputValid.update(inputValid.regexFn(newValue,regexObj[type]))
                })
                break;
            case 'string':
                inputValid[valid]()
                break;
            default:
                throw new Error(`input-valid指令未定义“${type}”参数`)
        }
    }
}
// 传入数据是否非法
function isInvalid(value) {
    return value === null || value === undefined || value === ''
}
// 如果是number类型 转换为字符串
const numberToString = function(value) {
    if(typeof value === 'number'){
        return value.toString()
    }
    return value
}

export default input_valid

